#include <utils/string.h>
#include <utils/debug.h>

size_t strlen(const char *str) {
    size_t len;
    for(len = 0; *str != '\0'; str++) len++;
    return len;
}

void itoa(char *buf, uint8 base, int32 value) {
    char *p = buf;
    char *p1, *p2;
    uint32 ud = value;
    uint32 divisor = 10;
    assert(base == 'd' || base == 'x');

    // fix base value if negative
    if (base == 'd' && value < 0) {
        *p++ = '-';
        buf++;
        ud = -value;
    }else if(base == 'x') {
        divisor = 16;
    }
    
    // convert each digit to char representation
    do {
        int32 rem = ud % divisor;
        char c = (rem < 10) ? rem + '0' : rem + 'a' - 10;
        *p++ = c;
    } while(ud /= divisor);
    
    // end string
    *p = 0;

    // reverse
    p1 = buf;
    p2 = p - 1;
    while(p1 < p2) {
        char tmp = *p1;
        *p1 = *p2;
        *p2 = tmp;
        p1++;
        p2--;
    }
}

void *memcpy(void *dest,const void *src, uint32 count) {
    const uint8 *sp = (const uint8*)src;
    uint8 *dp = dest;
    while(count--){
        *dp++ = *sp++;
    }
    return dest;
}

void *memset(void *dest, uint8 val, uint32 count) {
    uint8 *temp = (uint8*)dest;
    while (count--){
        *temp++ = val;
    }
    return dest;
}

uint16 *memsetw(uint16 *dest, uint16 val, uint32 count) {
    uint16 *temp = dest;
    while(count--){
        *temp++ = val;
    }
    return dest;
}

uint8 memcmp(void* arr1, void* arr2, uint32 count) {
    uint8 *t1 = (uint8*)arr1;
    uint8 *t2 = (uint8*)arr2;
    while(count--) {
        if (*t1 != *t2) {
            return 0;
        }
    }
    return 1;
}

char *strcpy(char *dest, char *src) {
    char *d = dest;
    while (*src) {
        *dest++ = *src++;
    }
    return d;
}

char *strncpy(char *dest, char *src, uint32 size) {
    uint32 i;
    for (i = 0;i < size && src[i] != 0; i++) {
        dest[i] = src[i];
    }

    for (; i < size; i++) {
        dest[i] = 0;
    }

    return dest;
}

char *strcat(char *dest, char *src) {
    char *d = dest;
    dest += strlen(dest);
    while (*src) {
        *dest++ = *src++;
    }
    *dest = 0;
    return d;
}

char *strncat(char *dest, char *src, uint32 size) {
    uint32 len = strlen(dest);
    uint32 i;
    for (i = 0;i < size && src[i] != 0; i++) {
        dest[len + i] = src[i];
    }
    dest[len + i] = 0;

    return dest;
}
